﻿#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "dialog.h"

#include <QDebug>
#include <QImage>
#include <QPixmap>

#include <QFileDialog>
#include <QKeySequence>

#include <QMessageBox>


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    threshold_value(90),
    center_offset(0),
    open_operation(5),
    dialog(nullptr),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    init();
}

MainWindow::~MainWindow()
{
    delete ui;

}

void MainWindow::init()
{
    init_show();
    init_connect();
}

#include <QDir>
#include <QIcon>

void MainWindow::init_show()
{
    ui->action->setShortcut(QKeySequence("Ctrl+o"));

    ui->tabWidget->removeTab(0);
    ui->tabWidget->removeTab(0);

    setWindowTitle(ui->title->text());

    QString path=QDir::currentPath();

    setWindowIcon(QIcon(path+"/../kerf_check/image/icon/icon.jpg"));

}

void MainWindow::init_connect()
{
    connect(ui->action,&QAction::triggered,this,&MainWindow::slot_openfile);
    connect(ui->action_2,&QAction::triggered,this,&MainWindow::slot_change_threshold_value);

}

void MainWindow::load_image(QString url)
{
    using namespace cv;
    clear_show();

    Mat temp_1;
    Mat temp_mat=cv::imread(url.toStdString());

    //将原图存储
    Mat temp_2=temp_mat.clone();

    double t = (double)getTickCount();

    //将图像转换为灰度图
    cvtColor(temp_mat,temp_mat,CV_BGR2GRAY);
    QString temp1=ui->label->text();
    add_to_map(temp1,ImgTransition::cvMat2QImage(temp_mat));

    qDebug()<<temp_mat.step;

//    进行直方图均衡
//    equalizeHist(temp_mat,temp_mat);
//    add_to_map("bbbb",ImgTransition::cvMat2QImage(temp_mat));

//    进行高斯滤波
    blur(temp_mat,temp_mat,Size(3,3));
    QString temp2=ui->label_2->text();
    add_to_map(temp2,ImgTransition::cvMat2QImage(temp_mat));

    //进行阈值分割
    threshold(temp_mat,temp_mat,threshold_value,0,THRESH_TOZERO);
    QString temp3=ui->label_3->text();
    add_to_map(temp3,ImgTransition::cvMat2QImage(temp_mat));

    //开运算排除小物体
    Mat element = getStructuringElement(MORPH_RECT,Size(open_operation,open_operation));

    morphologyEx(temp_mat,temp_mat,MORPH_OPEN,element);


    //进行边缘提取
    cv::Canny(temp_mat,temp_1,100,40,3);
    QString temp4=ui->label_4->text();
    add_to_map(temp4,ImgTransition::cvMat2QImage(temp_1));


    int temp=temp_1.rows;

    temp=temp*0.50+center_offset;



    qDebug()<<temp;

    for(int i=0;i<temp_1.cols;i++)
    {
        bool flag=true;
        for(int j=temp+1;j<temp_1.rows;j++)
        {
            if(flag)
            {
                if(temp_1.at<uchar>(j,i)!=0)
                    flag=false;
            }
            else
            {
                temp_1.at<uchar>(j,i)=255;
            }
        }
        flag=true;
        for(int j=temp;j>=0;j--)
        {
            if(flag)
            {
                if(temp_1.at<uchar>(j,i)!=0)
                    flag=false;
            }
            else
            {
                temp_1.at<uchar>(j,i)=255;
            }
        }
    }

    QString temp5=ui->label_5->text();
    add_to_map(temp5,ImgTransition::cvMat2QImage(temp_1));




    //!记录最大崩边的行
    int upper_chip=0;
    int lower_chip=0;
    count_chip(temp_1,upper_chip,lower_chip);



    //!记录刀痕的上下边缘
    int up_cut_line=0;
    int low_cut_line=0;

    count_cutline(temp_1,upper_chip,lower_chip,up_cut_line,low_cut_line);



    qDebug()<<"up chip is "<<upper_chip;
    qDebug()<<"low chip is "<<lower_chip;

    qDebug()<<"up cutline is "<<up_cut_line;
    qDebug()<<"low cutline is "<<low_cut_line;



    paint_chip(temp_2,temp_1,upper_chip,lower_chip,up_cut_line,low_cut_line);
    add_to_map(QStringLiteral("6渲染后的图像"),ImgTransition::cvMat2QImage(temp_2));


    QString show_str;

//    QMessageBox::information(ui->centralWidget,"","dddddd");

    t=(double)getTickCount()-t;

    qDebug()<<t*1000/getTickFrequency()<<" ms";

    add_show();

}

void MainWindow::clear_map()
{
    auto iter=img_widget.begin();

    while (iter!=img_widget.end()) {
        iter.value()->deleteLater();
        iter++;
    }
    img_widget.clear();
}

void MainWindow::clear_img_show_list()
{
    if(!img_show.empty())
    {
        qDeleteAll(img_show.begin(),img_show.end());
        img_show.clear();
    }
}

void MainWindow::add_img_to_lab(QLabel *lab, QImage &img)
{
    lab->setGeometry(0,0,img.width(),img.height());
    lab->setPixmap(QPixmap::fromImage(img));
}

void MainWindow::add_to_map(QString key, QImage img)
{
    img_widget.insert(key,new QWidget());
    img_show.insert(key,new QLabel);
    img_map.insert(key,img);

}

void MainWindow::chage_tab_widget_size()
{
    auto iter=img_widget.begin();

    while (iter!=img_widget.end()) {
        iter.value()->setGeometry(0,0,mainwindows_width,mainwindows_heigth);
        iter++;
    }

    for(QScrollArea *temp:show_aear)
    {
        temp->setGeometry(0,0,mainwindows_width,mainwindows_heigth-20);
    }
}


void MainWindow::clear_show()
{
    int count_tab=ui->tabWidget->count();
    for(int i=0; i<count_tab; i++)
    {
        ui->tabWidget->removeTab(0);
    }
    clear_map();
    clear_img_show_list();
}

void MainWindow::add_show()
{
    auto iter1 = img_widget.begin();

    while (iter1!=img_widget.end()) {
        ui->tabWidget->addTab(iter1.value(),iter1.key());

        QScrollArea* area=new QScrollArea(iter1.value());
        show_aear.push_back(area);
        add_img_to_lab(img_show[iter1.key()],img_map[iter1.key()]);
        area->setWidget(img_show[iter1.key()]);
        iter1.value()->setGeometry(0,0,ui->centralWidget->width(),ui->centralWidget->height()-20);
        qDebug()<<iter1.value()->size();
        area->setGeometry(0,0,iter1.value()->width(),iter1.value()->height());
        area->show();
        iter1++;
    }
}

void MainWindow::resizeEvent(QResizeEvent *event)
{
    mainwindows_width  = ui->centralWidget->width();
    mainwindows_heigth = ui->centralWidget->height();

    ui->tabWidget->setGeometry(0,0,mainwindows_width,mainwindows_heigth);
    chage_tab_widget_size();
}

void MainWindow::count_chip(cv::Mat &mat, int &upper_line, int &lower_line)
{
    for(int i=0;i<mat.rows;i++)
    {
        bool flag_over=false;
        for(int j=100;j<mat.cols-100;j++)
        {

            if(mat.at<uchar>(i,j)!=255)
            {
                qDebug()<<i<<j<<mat.at<uchar>(i,j);
                flag_over=true;
                upper_line=i;
                break;
            }
        }
        if(flag_over)
            break;
    }

    for(int i=mat.rows-1;i>=0;i--)
    {
        bool flag_over=false;
        for(int j=100;j<mat.cols-100;j++)
        {
            if(mat.at<uchar>(i,j)!=255)
            {
                qDebug()<<i<<j<<mat.at<uchar>(i,j);
                flag_over=true;
                lower_line=i;
                break;
            }
        }
        if(flag_over)
            break;
    }
}

void MainWindow::count_cutline(cv::Mat &mat, int up_chip, int low_chip, int &up_line, int &low_line)
{
    for(int i=up_chip;i<low_chip;i++)
    {
        int count_0=0;
        for(int j=0;j<mat.cols;j++)
        {
            if(mat.at<uchar>(i,j)!=255)
                count_0++;
        }
        qDebug()<<"0 value count is "<<count_0;
        if(count_0>mat.cols*0.8)
        {
            up_line=i;
            break;
        }
    }

    for(int i=low_chip;i>up_chip;i--)
    {
        int count_0=0;
        for(int j=0;j<mat.cols;j++)
        {
            if(mat.at<uchar>(i,j)!=255)
                count_0++;
        }
        qDebug()<<"0 value count is "<<count_0;
        if(count_0>mat.cols*0.8)
        {
            low_line=i;
            break;
        }
    }
}

void MainWindow::paint_chip(cv::Mat &show, cv::Mat &cut_line, int up_chip, int low_chip, int up_line, int low_line)
{
    qDebug()<<"ddddd";
    for(int i=up_chip;i<up_line;i++)
    {
        qDebug()<<"ddddqqqq";
        for(int j=0;j<cut_line.cols;j++)
        {
            if(cut_line.at<uchar>(i,j)==0)
                show.at<cv::Vec3b>(i,j)[2]=255;
        }
    }

    for(int i=low_line;i<low_chip;i++)
    {
        for(int j=0;j<cut_line.cols;j++)
        {
            if(cut_line.at<uchar>(i,j)==0)
                show.at<cv::Vec3b>(i,j)[2]=255;
        }
    }



}

void MainWindow::slot_openfile()
{
    QString filePath;
    filePath=QFileDialog::getOpenFileName(this,
                                          "",
                                          "",
                                          "IMG(*.bmp);;All File(*)");
    qDebug()<<filePath;
    if(!filePath.isEmpty())
    {
        current_path=filePath;
        load_image(filePath);
    }
}

void MainWindow::slot_change_threshold_value()
{
    if(dialog!=nullptr)
        delete dialog;

    dialog = new Dialog(this);

    connect(dialog,&Dialog::sig_send_value,this,[&](int value[]){
        threshold_value=value[0];
        center_offset=value[1];
        open_operation=value[2];
        load_image(current_path);
    });

    int value[3];
    value[0]=threshold_value;
    value[1]=center_offset;
    value[2]=open_operation;



    dialog->set_value(value);
    dialog->setModal(true);
    dialog->show();

}
